package net.tv90.bfmccore.battlepack;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import net.tv90.bfmccore.unlock.ItemResources;
import org.bitterorange.flansmodslain.actions.Money;
import org.bitterorange.flansmodslain.actions.Point;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;

import java.io.*;
import java.nio.Buffer;
import java.nio.file.Files;
import java.util.*;
import java.util.stream.Collectors;

import static net.tv90.bfmccore.BFMCCore.PLUGIN_ROOT;
import static net.tv90.bfmccore.helper.FlanHelper.WeaponTypeMap;

public class BattlepackItemUtil {

    /*** 玩家已经拥有的战斗包 */
    public static Map<String, List<BattlepackItem>> playerBattlepackMap;
    /*** 战斗包对象池子 */
    public static List<BattlepackItem> battlepackItemPool = new ArrayList<>();
    public static Random random = new Random();

    static {
        BattlepackResource battlepackResource = BattlepackResource.getInstance();
        battlepackResource.load();
        initBattlepackData();
    }

    /**
     * 给予玩家战斗包物品
     * @param p 玩家
     */
    public static void getSingleBattlepackItem(Player p) {
        List<BattlepackItem> playerAlreadyHad = playerBattlepackMap.getOrDefault(p.getName(), new ArrayList<>());
//        List<BattlepackItem> playerNotHad = battlepackItemPool.stream().filter(e -> !playerAlreadyHad.contains(e)).collect(Collectors.toList());
        List<BattlepackItem> playerNotHad = battlepackItemPool.stream()
                .filter(e -> playerAlreadyHad.stream().noneMatch(item -> item.getContent().equals(e.getContent())))
                .collect(Collectors.toList());
        System.out.println("playerAlreadyHad " + playerAlreadyHad.size());
        System.out.println("playerNotHad " + playerNotHad.size());
        System.out.println("battlepackItemPool " + battlepackItemPool.size());
        Collections.shuffle(playerNotHad);
        int randomIndex = random.nextInt(playerNotHad.size());
        BattlepackItem bpi = playerNotHad.get(randomIndex);
        bpi.getBattlePackItem(p);
        if (bpi instanceof BattlepackGeneralItem) {
            playerAlreadyHad.add(bpi);
        }
        playerBattlepackMap.put(p.getName(), playerAlreadyHad);
        //System.out.println(playerBattlepackMap);
        savePlayerBattlepackData();
    }

    /*** 将玩家已经获得的战斗包物品序列化到文件 */
    public static void savePlayerBattlepackData() {
        File file = new File(PLUGIN_ROOT, "Battlepack/Battlepack.dat");
        try (
                OutputStream outputStream = Files.newOutputStream(file.toPath());
                ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream)
        ) {
            objectOutputStream.writeObject(playerBattlepackMap);
            System.out.println("储存战斗包数据成功");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*** 从文件读取玩家已经获得的战斗包物品 */
    public static Map<?, ?> readPlayerBattlepackData() {
        File file = new File(PLUGIN_ROOT, "Battlepack/Battlepack.dat");
        try (
                InputStream inputStream = Files.newInputStream(file.toPath());
                ObjectInputStream objectInputStream = new ObjectInputStream(inputStream)
        ) {
            Object object = objectInputStream.readObject();
            System.out.println("读取战斗包数据成功" + object);
            return (object == null) ? new HashMap<>() : (Map<?, ?>) object;
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.err.println("Failed to Read Battlepack Data!");
        return new HashMap<>();
    }

    /*** 初始化战斗包数据 */
    @SuppressWarnings("unchecked")
    public static void initBattlepackData() {
        try {
            playerBattlepackMap = (Map<String, List<BattlepackItem>>) readPlayerBattlepackData();
            System.out.println("初始化战斗包数据成功" + playerBattlepackMap);
            return;
        } catch (Exception e) {
            e.printStackTrace();
        }
        playerBattlepackMap = new HashMap<>();
    }

    public static abstract class BattlepackItem implements Serializable {
        private static final long serialVersionUID = -21862011186529L;
        public final @Getter String content;
        public final @Getter String level;
        public final @Getter double probability;

        public BattlepackItem(String content, String level, double probability) {
            this.content = content;
            this.level = level;
            this.probability = probability;
        }

        public abstract void getBattlePackItem(Player p);

        @Override
        public String toString() {
            return content;
        }
    }

    @Getter
    @EqualsAndHashCode(callSuper = true)
    public static class BattlepackGeneralItem extends BattlepackItem {
        private static final long serialVersionUID = -238760146352982L;
        //种类
        private final @Getter EnumBattlepackItemType type;

        public BattlepackGeneralItem(EnumBattlepackItemType type, String content, String level, double probability) {
            super(content, level, probability);
            this.type = type;
        }

        @Override
        public void getBattlePackItem(Player p) {
            System.out.println(p.getName() + "获得BattlepackGeneralItem " + content);
            if (type == EnumBattlepackItemType.MELEE) {
                String name = ItemResources.getName_LangById(content);
                p.sendMessage("§e[管理员]你于战斗包中获得了" + level + name + "的解锁权限");
                Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "lp user " + p.getName() + " permission set unlock." + content);
                Battlepack.showWeaponHUD(p, ItemResources.getNameById(content.split("_")[0]), "Battlepack_Out_Epic");
            } else if (type == EnumBattlepackItemType.ATTACHMENT) {
                String name = ItemResources.getName_LangById(content.split("_")[0]);
                String country = content.split("_")[1];
                String weaponType = WeaponTypeMap.get(content.split("_")[2].toUpperCase());
                switch (country) {
                    case "ru": {
                        country = "俄国";
                        break;
                    }
                    case "us": {
                        country = "美国";
                        break;
                    }
                    case "cn": {
                        country = "中国";
                        break;
                    }
                }
                p.sendMessage("§e[管理员]你于战斗包中获得了" + level + country + weaponType + "武器配件" + name + " (序列号:" + content + ")");
                Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "lp user " + p.getName() + " permission set unlock." + content);
                Battlepack.showItemHUD(p, ItemResources.getNameById(content.split("_")[0]), "Battlepack_Out_Normal");
            }
        }
    }

    public static class BattlepackRank extends BattlepackItem {
        private static final long serialVersionUID = -70138563807411L;
        public final @Getter int rankNum;

        public BattlepackRank(String content, String level, double probability, int rankNum) {
            super(content, level, probability);
            this.rankNum = rankNum;
        }

        @Override
        public void getBattlePackItem(Player p) {
            for(int i = 0 ; i < rankNum / 100; ++i){
                Point.add(p, 100);
            }
            System.out.println(p.getName() + "获得BattlepackRank " + content);
            p.sendMessage("§e[管理员]你于战斗包中获得了" + level + rankNum + "军衔");
        }
    }

    public static class BattlepackMoney extends BattlepackItem {
        private static final long serialVersionUID = 1596309601135L;
        public final @Getter int moneyNum;

        public BattlepackMoney(String content, String level, double probability, int moneyNum) {
            super(content, level, probability);
            this.moneyNum = moneyNum;
        }

        @Override
        public void getBattlePackItem(Player p) {
            Money.give(p, moneyNum);
            System.out.println(p.getName() + "获得BattlepackMoney " + content);
            p.sendMessage("§e[管理员]你于战斗包中获得了" + level + moneyNum + "金币");
        }
    }
}